/**
 * Copyright (C), 2001-2031, www.bosssof.com.cn
 * FileName: AppLogImpl.java
 * Author: abel.zhan
 * Date: 2024-05-28 14:25
 * Description:
 * 用于时间AppLog注解
 * History:
 * Date          Author   Version  Desc
 * 2024-01-01    bosssoft  1.0.0   initialize this file
 */
package com.bosssoft.common.annotation.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @className: AppLogImpl
 * @description: 实现以下功能：
 * 功能1 xxx
 * 功能2 xxx
 * 主要方法和数据成员：
 * methodxx 使用 ThreadPoolExecutor创建线程进行任务操作
 * 注意事项：
 * 事项1: 该类需要从容器获取不可以new
 * @author: abel.zhan
 * @date: 2024-05-2814:25
 * @since 1.0
 **/

/**
 * AppLogImpl 类是一个 AOP 切面，用于在方法执行前后记录日志信息。
 * 使用 @Slf4j 注解自动生成日志记录器。
 */
@Slf4j
@Aspect
@Component
public class AppLogAspect {

    /**
     * 定义一个切点，匹配所有标注了 @AppLog 注解的方法。
     */
    @Pointcut("@annotation(com.bosssoft.common.annotation.AppLog)")
    public void appLog() {
    }

    /**
     * 环绕通知，在标注了 @AppLog 注解的方法执行前后进行日志记录。
     *
     * @param joinPoint 连接点，表示被拦截的方法
     * @return 方法的执行结果
     * @throws Throwable 如果方法执行过程中出现异常，将抛出该异常
     */
    @Around("appLog()")
    public Object appLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录方法开始时间
        Long startTime = System.currentTimeMillis();

        // 记录方法名称和开始执行日志
        log.info("开始执行方法 {}", joinPoint.getSignature().getName());

        // 记录方法参数
        Object[] params = joinPoint.getArgs();
        Arrays.stream(params).forEach(param -> log.info("参数 {}", param));

        // 执行目标方法
        Object result = joinPoint.proceed();

        // 记录方法执行时间
        log.info("消耗时间 {}", System.currentTimeMillis() - startTime);

        // 返回方法的执行结果
        return result;
    }
}

